{ "cells": [ { "cell_type": "markdown", "id": "586b41e3", "metadata": {}, "source": [ "# 02 - Precipitation Deterministic Forecasts" ] }, { "cell_type": "markdown", "id": "2fff6a2f", "metadata": {}, "source": [ "## Learning goals of this module\n", "- Learn how to do a basic analysis, comparing observed precipitation with forecast precipitation from GDPS\n", "- Learn how to calculate and visualize simple error metrics\n", "\n", "## Assumptions\n", "- We assume you are familiar with the concept of a __forecast__, and a __lead_time__. \n", "\n", "### Reference to data products\n", "\n", "- [Global Deterministic Prediction System (GDPS)](https://open.canada.ca/data/en/dataset/c041e79a-914a-5a4e-a485-9cbc506195df)\n" ] }, { "cell_type": "markdown", "id": "2d50a567", "metadata": {}, "source": [ "## Run imports and set-up logging" ] }, { "cell_type": "code", "execution_count": 1, "id": "edc0b447", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2026-06-18 22:43:42,381 - INFO - Running Veriflow version 0.1.0\n" ] } ], "source": [ "import logging\n", "import sys\n", "import warnings\n", "from pathlib import Path\n", "\n", "from dotenv import load_dotenv\n", "\n", "from veriflow import run_pipeline\n", "from veriflow.constants import VERSION\n", "\n", "# add project root (parent of notebook folder) to path\n", "sys.path.append(str(Path(\"..\").resolve()))\n", "\n", "\n", "from verification_plots import (\n", " crps_plot,\n", " forecast_timeseries_plot,\n", ")\n", "\n", "# Reload automatically\n", "%load_ext autoreload\n", "%autoreload 2\n", "\n", "\n", "warnings.filterwarnings(\"ignore\", category=RuntimeWarning)\n", "warnings.filterwarnings(\"ignore\", category=FutureWarning)\n", "\n", "load_dotenv(dotenv_path=\"tutorial.env\", override=True)\n", "\n", "base_config = Path(\"config\")\n", "base_config.exists()\n", "\n", "logging.basicConfig(\n", " level=logging.INFO,\n", " format=\"%(asctime)s - %(levelname)s - %(message)s\",\n", " handlers=[logging.StreamHandler()],\n", ")\n", "logging.info(f\"Running Veriflow version {VERSION}\")" ] }, { "cell_type": "markdown", "id": "8f1f1588", "metadata": {}, "source": [ "## Inspecting the _veriflow_ pipeline configuration\n", "1. Open the config file in the \"config\" directory. The name of the file is identical to the name of the notebook.\n", "2. Inspect each of the sections to gain an understanding of what this configuration is about." ] }, { "cell_type": "markdown", "id": "ec89e13b", "metadata": {}, "source": [ "## Running the _veriflow_ pipeline" ] }, { "cell_type": "code", "execution_count": 8, "id": "b339ac88", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2026-06-18 22:46:37,568 - INFO - Successfully initialized the configuration. \n", "\t verification_period_start = 2026-05-15 00:00:00 \n", "\t verification_period_end = 2026-06-01 00:00:00\n", "2026-06-18 22:46:37,570 - INFO - Start getting data from FewsWebservice.\n", "2026-06-18 22:46:37,991 - INFO - Successfully got observed data from FewsWebservice.\n", "2026-06-18 22:46:37,993 - INFO - Start getting data from FewsWebservice.\n", "2026-06-18 22:46:38,511 - INFO - Successfully got simulated data from FewsWebservice.\n", "2026-06-18 22:46:38,514 - INFO - Successfully loaded all data from sources.\n", "2026-06-18 22:46:38,544 - INFO - Successfully computed ContinuousScores for verification pair PC.\n", "2026-06-18 22:46:38,545 - INFO - Verification pipeline completed successfully.\n" ] } ], "source": [ "ods = run_pipeline((base_config / \"02_elbow_deterministic_forecast.yaml\", \"yaml\"))" ] }, { "cell_type": "markdown", "id": "0d7caa3a", "metadata": {}, "source": [ "## Evaluating the results in the _veriflow_ `OutputDataset`" ] }, { "cell_type": "markdown", "id": "cb8dd8d5", "metadata": {}, "source": [ "Verification metrics and results can contain a level of abstraction. Although these abstractions can reveal important information about forecast quality, a basic \"eyeball verification\" is often the best and intuitive way to start your verification exercise. You'll likely find strengths and weaknesses in your forecasts early on, without directly diving into levels of abstraction. In addition, a solid visual inspection may help you later on in understanding or explaining the more abstract results." ] }, { "cell_type": "markdown", "id": "d178a47e", "metadata": {}, "source": [ "### 1 - Visual inspection of observed and forecast data\n", "A good starting point for \"eyeball\" verification is simple: just looking at your observations and forecasts in a visual way. Use the interactive elements in the plots below to zoom, pan and compare the results of our 3 NWP products." ] }, { "cell_type": "code", "execution_count": 3, "id": "ab797cc8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Stations: ['3031092' '3050778' 'MSC-005' '05BL813' '05BJ804' '05BL809' 'FIRES-B4'\n", " '05BJ805' '05BL812' 'FIRES-B5' '05BJ806' '05BH803' '05BF825' '05BH802'\n", " '05BL810' '05BF827']\n", "GDPS Lead times (hours): [np.int64(24), np.int64(48), np.int64(72), np.int64(96), np.int64(120), np.int64(144), np.int64(168)]\n" ] } ], "source": [ "stations = ods.get(ods.verification_pairs[0]).coords[\"station\"].values\n", "\n", "lead_times = ods.get(ods.verification_pairs[0]).coords[\"lead_time\"].values\n", "lead_times_hours = [lt.astype(\"timedelta64[h]\").astype(int) for lt in lead_times]\n", "\n", "print(f\"Stations: {stations}\")\n", "print(f\"GDPS Lead times (hours): {lead_times_hours}\")" ] }, { "cell_type": "code", "execution_count": 4, "id": "9b157dad", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "